Vite + Vitest の環境に husky を導入してみた
はじめに
こんにちは。アノテーションの及川です。
前回ご紹介したこちらの記事の続きとして、Vite + Vitest の環境に husky を導入してみたので、その実施手順を整理しました。
husky の概要
- Git フックを簡単に管理できる仕組み(ツール)
- Git フックとは、
git commit
やgit push
などが発生したときに自動的に実行されるスクリプトのこと - husky を導入することで、ソースコードをコミットやプッシュする前に自動的にテストを実行する他、コードの内容が実行された際にエラーになりそうな部分を未然に指摘したり、ソースコードのインデントなどのフォーマットを整えたりすることが可能
想定される使用例(参考)
husky を使用するとコードの品質を保つため、下記のようなことが実現できます。
- 開発者がコードの変更をステージングし、コミットしようとする
- Husky がコミットする前に実行する pre-commit フックをトリガーして、lint-staged が実行される
- lint-staged がステージングされたファイルに対してリント(バグに繋がりやすい記述などの確認)やその他のチェックを行う
- すべてのチェックが通過(Pass)すれば、コミットは成功
- チェックに失敗するとコミットは中断され、開発者は問題を修正して再度コミットを行う(手順1.から実施)
husky 導入の補足
前述にもちらっと記載しましたが、husky の設定および検証を行う上で必要な、JavaScript(または、TypeScript) コードの構文エラーやスタイル違反を検出し、修正するための静的コード解析ツールである、ESLint と、コードのフォーマットを統一し、読みやすく整形するためのコードフォーマッターである Prettier を並行して設定します。
ESlint の設定
ESlint のインストール
下記コマンドで ESlint をインストールしてください。
% npm i -D eslint
ESlint 初期化
下記のように、ESlint の初期化を行ってください。
最後に "Successfully~" の文言が表示されれば OK です。
(例として、今回の検証では下記のように設定していいます。下記の例を参考にご自身の開発環境に合わせて設定をお試しください。)
% npx eslint --init You can also run this command directly using 'npm init @eslint/config'. ? How would you like to use ESLint? … To check syntax only ❯ To check syntax and find problems To check syntax, find problems, and enforce code style % npx eslint --init You can also run this command directly using 'npm init @eslint/config'. ✔ How would you like to use ESLint? · problems ? What type of modules does your project use? … ❯ JavaScript modules (import/export) CommonJS (require/exports) None of these % npx eslint --init You can also run this command directly using 'npm init @eslint/config'. ✔ How would you like to use ESLint? · problems ✔ What type of modules does your project use? · esm ? Which framework does your project use? … ❯ React Vue.js None of these % npx eslint --init You can also run this command directly using 'npm init @eslint/config'. ✔ How would you like to use ESLint? · problems ✔ What type of modules does your project use? · esm ✔ Which framework does your project use? · react ? Does your project use TypeScript? … No ❯ Yes % npx eslint --init You can also run this command directly using 'npm init @eslint/config'. ✔ How would you like to use ESLint? · problems ✔ What type of modules does your project use? · esm ✔ Which framework does your project use? · react ✔ Does your project use TypeScript? · typescript ? Where does your code run? … (Press <space> to select, <a> to toggle all, <i> to invert selection) ✔ Browser Node % npx eslint --init You can also run this command directly using 'npm init @eslint/config'. ✔ How would you like to use ESLint? · problems ✔ What type of modules does your project use? · esm ✔ Which framework does your project use? · react ✔ Does your project use TypeScript? · typescript ✔ Where does your code run? · browser The config that you've selected requires the following dependencies: eslint, globals, @eslint/js, typescript-eslint, eslint-plugin-react ? Would you like to install them now? › No / Yes % npx eslint --init You can also run this command directly using 'npm init @eslint/config'. ✔ How would you like to use ESLint? · problems ✔ What type of modules does your project use? · esm ✔ Which framework does your project use? · react ✔ Does your project use TypeScript? · typescript ✔ Where does your code run? · browser The config that you've selected requires the following dependencies: eslint, globals, @eslint/js, typescript-eslint, eslint-plugin-react ✔ Would you like to install them now? · No / Yes ? Which package manager do you want to use? … ❯ npm yarn pnpm bun % npx eslint --init You can also run this command directly using 'npm init @eslint/config'. ✔ How would you like to use ESLint? · problems ✔ What type of modules does your project use? · esm ✔ Which framework does your project use? · react ✔ Does your project use TypeScript? · typescript ✔ Where does your code run? · browser The config that you've selected requires the following dependencies: eslint, globals, @eslint/js, typescript-eslint, eslint-plugin-react ✔ Would you like to install them now? · No / Yes ✔ Which package manager do you want to use? · npm ☕️Installing... added 61 packages, changed 10 packages, and audited 396 packages in 5s 141 packages are looking for funding run `npm fund` for details found 0 vulnerabilities Successfully created /Users/anote.taro/dev/Introduction-to-React-Testing-with-Vitest/vitest-setup-test/eslint.config.js file.
ESlint の公式ドキュメントにも使用方法について記載がされておりますので、適宜ご参照ください。
Prettier の設定
Prettier のインストール
下記コマンドで Prettier をインストールしてください。
% npm i -D prettier
Prettier 設定ファイルの作成
prettier.config.js ファイルを作成してください。
% touch prettier.config.js
作成したら、お好みで下記のような設定ファイルを作成してください。
/** @type {import("prettier").Config} */ const config = { trailingComma: 'es5', tabWidth: 2, semi: false, singleQuote: true, } export default config
下記、Prettier 公式ドキュメントにも記載例があるので、参考情報として適宜ご参照ください。
Git の設定
プロジェクト配下で git が初期化されていなければ後述の設定を行ってください。
GitHub (リモート)リポジトリの作成
詳細な手順は本記事では割愛致しますが、下記の公式ドキュメントなどを参考に作成してください。
ローカル環境の Git の初期化設定
下記のコマンド例や公式ドキュメントを参考に、ローカル環境にて Git の初期化を実施してください。
% git init % git branch -M main % git remote add origin git@github.com:<user名>/<リポジトリ名>.git # 前述の GitHub リポジトリ名を参照して入力してください。 % git remote -v # (任意) push or pull する GitHub リモートリポジトリが設定されているかを確認できます。
husky の設定
husky のインストール
下記のコマンドで、husky をインストールします。
% npm i -D husky
husky の初期化
下記のコマンドで、husky を初期化します。
% npx husky init
lint-staged のインストール
git commit
や git push
を実行する前に ESlint や Prettier を実行するために必要な lint-staged をインストールします。
% npm i -D lint-staged
packgae.json の編集
lint-staged
の設定を加えます。
また、プッシュ前(pre-push)に テストを実行させたいので scripts
を下記のように変更します。
"scripts": { "test": "vitest --run" }, "lint-staged": { "*.{js,jsx,ts,tsx}": [ "eslint --fix", "prettier --write" ] }
pre-commit の編集
pre-commit ファイルに下記を追記してください。
npx lint-staged
pre-push の作成
% touch .husky/pre-push
で pre-push ファイルを作成して下記を追記してください。
npm run test
husky の実行テスト
適当にファイルを編集する
husky の動作確認を行うため、前回のブログで検証用に作成した下記ファイルを一部変更します。
- src/components/Input/TextInput.test.tsx
import React from 'react' import { render, screen } from '@testing-library/react' import userEvent from '@testing-library/user-event' import TextInput from './TextInput' ~~ 中略 ~~ test('TextInput Event Test 2', async () => { // 'TextInput Event Test 1' → 'TextInput Event Test 2' に変更 ~~ 後略 ~~~
git commit コマンドまで実施してみる
git commit まで実施してみると、husky(lint-staged)が正常に動作していることが確認できました。
% git add . % git commit -m "テストタイトルを1から2に修正" ✔ Preparing lint-staged... ✔ Running tasks for staged files... ✔ Applying modifications from tasks... ✔ Cleaning up temporary files... [main 65bacbf] テストタイトルを1から2に修正 1 file changed, 1 insertion(+), 1 deletion(-)
git push コマンドで GitHub リポジトリに変更内容をプッシュする
git push コマンドを実行すると、Vitest のテストが実行されていることも確認することができます。
% git push origin main > vitest-setup-test@0.0.0 test > vitest --run RUN v1.4.0 /Users/anote.taro/dev/Introduction-to-React-Testing-with-Vitest/vitest-setup-test ✓ src/components/Input/TextInput.test.tsx (2) ✓ TextInput Component test ✓ TextInput Event Test 4 Test Files 1 passed (1) Tests 2 passed (2) Start at 20:39:30 Duration 586ms (transform 149ms, setup 131ms, collect 173ms, tests 45ms, environment 95ms, prepare 50ms) Enumerating objects: 11, done. Counting objects: 100% (11/11), done. Delta compression using up to 8 threads Compressing objects: 100% (6/6), done. Writing objects: 100% (6/6), 551 bytes | 551.00 KiB/s, done. Total 6 (delta 3), reused 0 (delta 0), pack-reused 0 remote: Resolving deltas: 100% (3/3), completed with 3 local objects. To github.com:<user名>/<リポジトリ名>.git a613e55..65bacbf main -> main
まとめ
Vite + Vitest の環境に husky を導入するまでのハンズオンの過程を記載しました。
この記事が誰かのお役に立てば幸いです。
アノテーション株式会社について
アノテーション株式会社はクラスメソッドグループのオペレーション専門特化企業です。サポート・運用・開発保守・情シス・バックオフィスの専門チームが、最新 IT テクノロジー、高い技術力、蓄積されたノウハウをフル活用し、お客様の課題解決を行っています。当社は様々な職種でメンバーを募集しています。「オペレーション・エクセレンス」と「らしく働く、らしく生きる」を共に実現するカルチャー・しくみ・働き方にご興味がある方は、アノテーション株式会社 採用サイトをぜひご覧ください。